package com.myk.game.gobangchess.rooms.oldrooms;

import com.myk.game.gobangchess.DataManager;
import com.myk.game.gobangchess.Room;
import com.myk.game.gobangchess.Sign;
import com.myk.game.gobangchess.constants.ColorCost;
import com.myk.game.gobangchess.constants.WinMode;
import com.myk.game.gobangchess.rooms.absrooms.movechess.MoreColorCost;
import com.myk.game.gobangchess.rooms.absrooms.movechess.MovedChess;
import com.myk.game.gobangchess.rooms.absrooms.movechess.MovedChessRoom;
import com.myk.game.gobangchess.signs.*;
import com.myk.game.gobangchess.utils.GridsUtils;
import com.myk.game.gobangchess.utils.Pair;

import java.util.ArrayList;
import java.util.List;

/**
 * 双步突破棋
 */
public class TwoStepBreakThroughRoom extends Room implements MovedChessRoom {
    private final List<MovedChess> chessList = new ArrayList<>();
    private MovedChess selectedChess;
    private MovedChess lastMovedChess;
    private int curStep = 1; // 当前玩家步数用来轮换
    private final List<int[]> moveArrayList = new ArrayList<>(2); // 走子标记

    private final CacheSign cacheSign;

    public TwoStepBreakThroughRoom(String roomName) {
        super(roomName, "兵阵推进的练习棋，一次可走两步", "双步突破棋", GridsUtils.createEmptyGrids(10, 10), true, true);
        cacheSign = new CacheSign(this, "background", 3, true, drawBackground()); //*** 修改背景样式记得改这里的版本号！！！
    }

    private List<Sign> drawBackground() {
        List<Sign> chessboardStyle = new ArrayList<>();
        int row = curGrids.length;
        int col = curGrids[0].length;
        //绘制类似国际象棋的黑白相间的格子
        List<Integer> bGrids = new ArrayList<>();
        List<Integer> wGrids = new ArrayList<>();
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                int index = getIndex(i, j);
                if ((i + j) % 2 == 0) {
                    bGrids.add(index);
                }
                else {
                    wGrids.add(index);
                }
            }
        }
        chessboardStyle.add(new ColorSign(bGrids, "#FF888888"));
        chessboardStyle.add(new ColorSign(wGrids, "#FFDDDDDD"));
        return chessboardStyle;
    }

    @Override
    public String getCoordMode() {
        return "41410000";
    }

    @Override
    public String getRuleText() {
        return "双方轮流每次各走两个棋子各一步，先手第一步只能走一个棋子一步。\n" +
                "走子可以前进一格或者斜进一格，吃子为斜进一格或者后退一格。\n" +
                "先把两枚棋子走到对方底线就获胜。\n" +
                "无法正常完成走两步棋时判负。";
    }

    @Override
    public CacheSign getCacheSignByName(String cacheName) {
        return cacheSign;
    }

    @Override
    public String getGameInfo() {
        //先清空棋盘
        curGrids = GridsUtils.copyGrids(originGrids);
        signList.clear();
        signList.add(cacheSign);
        this.render();
        //画一下箭头
        for (int[] moveArray : moveArrayList) {
            signList.add(new LineSign(moveArray[0], moveArray[1], ColorCost.MOVE_ARROW_LIGHT, 1));
        }
        return super.getGameInfo();
    }

    @Override
    public void resetGrids() {
        super.resetGrids();
        chessList.clear();
        selectedChess = null;
        lastMovedChess = null;
        moveArrayList.clear();
        curStep = 1;
    }

    @Override
    protected void onStartPrepare() {
        for (int i = 0; i < curGrids[0].length; i++) {
            chessList.add(new Pawn(1, 0, i));
            chessList.add(new Pawn(1, 2, i));
            chessList.add(new Pawn(2, 7, i));
            chessList.add(new Pawn(2, 9, i));
        }
        noticeBlackMove();
    }

    @Override
    public void doRule(int row, int col, int value) {
        if (selectOrMove(row, col)) {
            stepAdd();
            // 判断下一手是否无棋可走
            boolean canMove = false;
            // 判断是否走到了对面底线
            int countGeneral = 0;
            for (MovedChess chess : chessList) {
                if (chess.getSide() == value && ((Pawn) chess).inEnemyBoard(this)) {
                    countGeneral++; //每有一枚棋子达到对方底线计数加一
                }
                if (chess.getSide() == getNextCur() && chess != lastMovedChess && (!chess.getMoveRange(this).isEmpty() || !chess.getEatRange(this).isEmpty())) {
                    canMove = true;
                }
            }
            if (countGeneral > 1) {
                if (cur == 1) {
                    doOver(WinMode.BLACK_WIN, "黑方突破成功获胜！");
                }
                else {
                    doOver(WinMode.WHITE_WIN, "白方突破成功获胜！");
                }
                return;
            }
            if (!canMove) {
                if (cur == 1) {
                    doOver(WinMode.BLACK_WIN, "黑方闷杀白方");
                }
                else {
                    doOver(WinMode.WHITE_WIN, "白方闷杀黑方");
                }
                return;
            }
            curStep++;
            if (cur == 1) {
                gameTip = "黑方还要走一步";
            }
            else {
                gameTip = "白方还要走一步";
            }
        }
        if (curStep == 2) {
            curStep = 0;
            lastMovedChess = null;
            if (cur == 1) {
                gameTip = "白方还要走二步";
                noticeWhiteMove();
            }
            else {
                gameTip = "黑方还要走二步";
                noticeBlackMove();
            }
        }
        else {
            noticeAllRefreshGameInfo();//通知界面刷新
        }
    }

    /**
     * 切换下一步行动的行动方（仍是自己或者对方）
     */
    private int getNextCur() {
        if (curStep == 0) {
            return cur;
        }
        else {
            return 3 - cur;
        }
    }

    /**
     * 选择或走子
     *
     * @param row 点击位置的row
     * @param col 点击位置的col
     * @return 是否走子成功
     */
    private boolean selectOrMove(int row, int col) {
        MovedChess target = getChessByPos(row, col);
        if (target == null && selectedChess == null) {
            // 既没有点击棋子，又没有已选中的棋子
            return false;
        }
        if (selectedChess == null) {
            // 选中棋子
            if (target == lastMovedChess) {
                gameTip = "不能连续移动同一个棋子";
                return false;
            }
            if (target.getSide() == cur){
                selectedChess = target;
            }
            return false;
        }
        if (selectedChess == target) {
            // 取消选中棋子
            selectedChess = null;
            noticeAllRefreshGameInfo();
            return false;
        }
        if (selectedChess.getSide() != cur) {
            // 选中的是对方的棋子，仅能查看，不能移动
            // 取消选中棋子
            selectedChess = null;
            noticeAllRefreshGameInfo();
            return false;
        }
        // 尝试走子
        int startIndex = getIndex(selectedChess.getRow(), selectedChess.getCol());
        int endIndex = getIndex(row, col);
        if (selectedChess.getMoveRange(this).contains(endIndex)) {
            selectedChess.moveTo(row, col);
            if (curStep == 0) {
                moveArrayList.clear();
            }
            moveArrayList.add(new int[]{startIndex, endIndex});
            lastMovedChess = selectedChess;
            selectedChess = null;
            return true;
        }
        else if (selectedChess.getEatRange(this).contains(endIndex)) {
            chessList.remove(getChessByPos(row, col));
            selectedChess.moveTo(row, col);
            if (curStep == 0) {
                moveArrayList.clear();
            }
            moveArrayList.add(new int[]{startIndex, endIndex});
            lastMovedChess = selectedChess;
            selectedChess = null;
            return true;
        }
        else {
            selectedChess = null;
            return false;
        }
    }

    @Override
    public List<MovedChess> getChessList() {
        return chessList;
    }

    @Override
    public MovedChess getSelectedChess() {
        return selectedChess;
    }

    @Override
    public int[][] getCurGrids() {
        return curGrids;
    }

    @Override
    public List<Sign> getSignList() {
        return signList;
    }

    @Override
    public MovedChess getChessByPos(int row, int col) {
        for (MovedChess chess : chessList) {
            if (chess.getRow() == row && chess.getCol() == col) {
                return chess;
            }
        }
        return null;
    }

    @Override
    public MovedChess getChessByIndex(int index) {
        for (MovedChess chess : chessList) {
            if (chess.getIndex(this) == index) {
                return chess;
            }
        }
        return null;
    }

    public static abstract class Chess implements MovedChess {
        public int row;
        public int col;
        private final int side;
        private final String name;

        public Chess(String name, int side, int row, int col) {
            this.name = name;
            this.side = side;
            this.row = row;
            this.col = col;
        }

        @Override
        public String getColor() {
            return getSide() == 1 ? MoreColorCost.RED_CHESS_WORD : MoreColorCost.WHITE_CHESS_WORD;
        }

        protected int getDirection() {
            if (getSide() == 1) {
                return 1;
            }
            else if (getSide() == 2) {
                return -1;
            }
            else {
                return 0;
            }
        }

        // 判断是否在敌方底线
        protected boolean inEnemyBoard(Room room) {
            if (getSide() == 1) {
                return getRow() == room.curGrids.length-1;
            }
            else {
                return getRow() == 0;
            }
        }

        @Override
        public int getRow() {
            return row;
        }

        @Override
        public int getCol() {
            return col;
        }

        @Override
        public void moveTo(int row, int col) {
            this.row = row;
            this.col = col;
        }

        @Override
        public int getSide() {
            return side;
        }

        @Override
        public String getName() {
            return name;
        }
    }

    private static class Pawn extends Chess {
        public Pawn(int mSide, int pRow, int pCol) {
            super("兵", mSide, pRow, pCol);
        }

        @Override
        public String getName() {
            //return getSide() == 1 ? "兵" : "卒";
            return "";
        }

        @Override
        public List<Integer> getMoveRange(MovedChessRoom room) {
            return genMoveRange(room, new int[][]{{getDirection(), 0}, {getDirection(), 1}, {getDirection(), -1}}, 1); //走子为直进一格或斜进一格
        }

        @Override
        public List<Integer> getEatRange(MovedChessRoom room) {
            return genEatRange(room, new int[][]{ {getDirection(), 1}, {getDirection(), -1}, {-getDirection(),0}}, 1); //吃子为斜进一格
        }
    }

}
